package in.muton.edushare.grading.panels.prevgrades.old;

import in.muton.edushare.pages.EduShareBasePage;
import in.muton.edushare.pages.common.EdusharePanel;
import in.muton.edushare.url.EduShareURLPanel;
import in.muton.edushare.wicket.models.CayenneList;
import in.muton.edushare.wicket.models.CayenneModel;
import in.muton.edushare.wicket.models.InnerList;

import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;

import com.edushare.common.dao.BatchDAO;
import com.edushare.common.dao.CurriculumDAO;
import com.edushare.common.dao.EnrolmentsDAO;
import com.edushare.common.dao.academics.grades.SGCalculation;
import com.edushare.common.orm.ORMInterface;
import com.edushare.common.vo.AcademicYearModel;
import com.edushare.common.vo.Batches;
import com.edushare.common.vo.CourseInstances;
import com.edushare.common.vo.Courses;
import com.edushare.common.vo.Enrolments;
import com.edushare.common.vo.Users;

public class StudentGradeEdit extends EdusharePanel {
	private int currSem = 0;
	private IModel<Users> userModel;
	private IModel<Batches> batchModel;
	private List<WebMarkupContainer> wmcList = new ArrayList<WebMarkupContainer>();

	public StudentGradeEdit(String id, IModel<Users> user,
			IModel<Batches> batch, int currSem, EduShareBasePage page) {
		super(id, page);
		this.currSem = currSem;
		this.userModel = user;
		this.batchModel = batch;

		Form<Void> f = new Form<Void>("gradeForm") {
			private static final long serialVersionUID = 3846028915457463166L;

			@Override
			public void onSubmit() {
			}
		};
		add(f);
		f.add(new Button("reset").setDefaultFormProcessing(false));
		f.add(new EduShareURLPanel("userURLPanel", userModel));
		WebMarkupContainer temp;
		f.add(temp = getRequiredSubjectsContainer());
		wmcList.add(temp);
		f.add(temp = getOptionalSubjectsContainer());
		wmcList.add(temp);
		f.add(temp = getUnlinkedSubjectsContainer());
		wmcList.add(temp);
		addGradeSummary(f);
	}

	private WebMarkupContainer getRequiredSubjectsContainer() {
		final NormalEnrolments n = new NormalEnrolments(getORMInterface(),
				userModel, currSem, batchModel);
		WebMarkupContainer wmc = new WebMarkupContainer("reqSubWMC") {
			@Override
			public boolean isVisible() {
				return n.getObject().size() > 0;
			}

			private static final long serialVersionUID = -2379661337591149163L;
		};
		wmc.add(new ListView<IModel<Enrolments>>("mandatoryCoursesLV", n) {
			@Override
			protected void populateItem(final ListItem<IModel<Enrolments>> arg0) {
				Enrolments e = arg0.getModelObject().getObject();
				IModel<CourseInstances> courseModel = new CayenneModel<CourseInstances>(
						e.getCourseInstance());
				arg0.add(new EduShareURLPanel("courseURL", courseModel));
				arg0.add(new IndicatingAjaxLink<Void>("delink") {
					private static final long serialVersionUID = 6744402933565398617L;

					@Override
					public void onClick(AjaxRequestTarget target) {
						new EnrolmentsDAO(getORMInterface())
								.unlinkEnrolmentFromBatch(arg0.getModelObject()
										.getObject());
						wmcList.get(2).setVisible(true);
						for (WebMarkupContainer wmc : wmcList) {
							target.addComponent(wmc);
						}
					}
				});
				arg0.add(new CourseGradeField("grade", userModel, batchModel,
						courseModel, currSem, 0));
			}

			private static final long serialVersionUID = 2664944387989486267L;
		});
		wmc.setOutputMarkupId(true);
		return wmc;
	}

	private WebMarkupContainer getOptionalSubjectsContainer() {
		final ElectiveModelInternal e = new ElectiveModelInternal(
				getORMInterface(), batchModel, currSem);
		WebMarkupContainer wmc = new WebMarkupContainer("electiveSubWMC") {
			private static final long serialVersionUID = 5780795477308744290L;

			@Override
			public boolean isVisible() {
				return e.getObject().size() > 0;
			}
		};
		wmc.add(new ListView<Integer>("electiveCoursesLV", e) {
			@Override
			protected void populateItem(ListItem<Integer> arg0) {
				int groupId = arg0.getModelObject();
				arg0.add(new Label("elNum", (groupId + 1) + ""));
				final CourseGradeField f = new CourseGradeField("grade",
						userModel, batchModel, ElectiveModel.getActiveInst(
								userModel, batchModel, currSem, groupId),
						currSem, groupId);
				arg0.add(f);
				ElectiveModel m = new ElectiveModel(userModel, batchModel, arg0
						.getModelObject(), f, currSem);
				final DropDownChoice<IModel<Courses>> ddc = new DropDownChoice<IModel<Courses>>(
						"electiveChoice", m, m.getOptionsList(), m);
				arg0.add(ddc);
				ddc.add(new AjaxFormComponentUpdatingBehavior("onchange") {
					@Override
					protected void onUpdate(AjaxRequestTarget target) {
						target.addComponent(ddc);
						target.addComponent(f);
					}

					private static final long serialVersionUID = 2850242486770696957L;
				});
			}

			private static final long serialVersionUID = 757094043959016720L;
		});
		wmc.setOutputMarkupId(true);
		return wmc;
	}

	private WebMarkupContainer getUnlinkedSubjectsContainer() {
		final UnlinkedEnrolments u = new UnlinkedEnrolments(getORMInterface(),
				batchModel, currSem, userModel);
		WebMarkupContainer wmc = new WebMarkupContainer("unlinkedSubWMC") {
			@Override
			public boolean isVisible() {
				return u.getObject().size() > 0;
			}

			private static final long serialVersionUID = 2443510946849919358L;
		};
		wmc.add(new ListView<IModel<Enrolments>>("unlinkedCoursesLV", u) {
			@Override
			protected void populateItem(final ListItem<IModel<Enrolments>> arg0) {
				Enrolments e = arg0.getModelObject().getObject();
				IModel<CourseInstances> courseModel = new CayenneModel<CourseInstances>(
						e.getCourseInstance());
				arg0.add(new EduShareURLPanel("courseURL", courseModel));
				arg0.add(new IndicatingAjaxLink<Void>("linkToProg") {
					private static final long serialVersionUID = 6744402933565398617L;

					@Override
					public void onClick(AjaxRequestTarget target) {
						new EnrolmentsDAO(getORMInterface())
								.linkEnrolmentToBatch(arg0.getModelObject()
										.getObject(), batchModel.getObject(),
										currSem);
						for (WebMarkupContainer wmc : wmcList) {
							target.addComponent(wmc);
						}
					}
				});
				arg0.add(new CourseGradeField("grade", userModel, batchModel,
						courseModel, currSem, 0));
			}

			private static final long serialVersionUID = 8014914416600576219L;
		});
		wmc.setOutputMarkupId(true);
		return wmc;
	}

	public static class NormalEnrolments extends InnerList<Enrolments> {
		private ORMInterface orm;
		private IModel<Users> userModel;
		private int currSem;
		private IModel<Batches> batchModel;

		public NormalEnrolments(ORMInterface orm, IModel<Users> userModel,
				int currSem, IModel<Batches> batchModel) {
			this.orm = orm;
			this.userModel = userModel;
			this.currSem = currSem;
			this.batchModel = batchModel;
		}

		@Override
		public List<IModel<Enrolments>> getObject() {
			EnrolmentsDAO eDAO = new EnrolmentsDAO(orm);
			BatchDAO bDAO = new BatchDAO(orm);
			int acadYear = bDAO
					.getCalendarYear(batchModel.getObject(), currSem);
			AcademicYearModel sem = bDAO.getAcadYearModel(batchModel
					.getObject(), currSem);
			return new CayenneList<Enrolments>(eDAO.getNormalEnrolments(
					userModel.getObject(), sem, acadYear, batchModel
							.getObject())).getObject();
		}

		private static final long serialVersionUID = 1482190609976482820L;
	}

	public static class UnlinkedEnrolments extends InnerList<Enrolments> {
		private IModel<Users> userModel;
		private ORMInterface orm;
		private IModel<Batches> batchModel;
		private int currSem;

		public UnlinkedEnrolments(ORMInterface orm, IModel<Batches> batchModel,
				int currSem, IModel<Users> userModel) {
			this.userModel = userModel;
			this.orm = orm;
			this.batchModel = batchModel;
			this.currSem = currSem;

		}

		@Override
		public List<IModel<Enrolments>> getObject() {
			EnrolmentsDAO eDAO = new EnrolmentsDAO(orm);
			BatchDAO bDAO = new BatchDAO(orm);
			int acadYear = bDAO
					.getCalendarYear(batchModel.getObject(), currSem);
			AcademicYearModel sem = bDAO.getAcadYearModel(batchModel
					.getObject(), currSem);
			return new CayenneList<Enrolments>(eDAO.getUnlinkedEnrolments(
					userModel.getObject(), sem, acadYear)).getObject();
		}

		private static final long serialVersionUID = 78024502290391930L;
	}

	public static class ElectiveModelInternal implements IModel<List<Integer>> {
		private ORMInterface orm;
		private IModel<Batches> batchModel;
		private int currSem;

		public ElectiveModelInternal(ORMInterface orm,
				IModel<Batches> batchModel, int currSem) {
			this.orm = orm;
			this.batchModel = batchModel;
			this.currSem = currSem;
		}

		public List<Integer> getObject() {
			int num = new CurriculumDAO(orm).getNumElectives(batchModel
					.getObject().getCurricula(), currSem);
			return makeList(1, num);
		}

		public void setObject(List<Integer> arg0) {
		}

		public void detach() {
		}

		private static final long serialVersionUID = -8193819407477049639L;
	}

	public static List<Integer> makeList(int start, int end) {
		List<Integer> list = new ArrayList<Integer>();
		for (int i = start; i <= end; i++) {
			list.add(i);
		}
		return list;
	}
	
	private void addGradeSummary(Form<Void> f){
		SGCalculation sgc = new SGCalculation(userModel.getObject(), batchModel
				.getObject(), currSem);
		int currCredits = sgc.getCredits();
		int creditsEarned = sgc.getSuccessfulCredits(getORMInterface());
		double sgpa = sgc.getSemGradePointAverage(getORMInterface());
		double cgpa = sgc.getCGPA(getORMInterface());
		int cumulativeCredits = sgc.getTotalCredits();
		int cumulativeCreditsEarned = sgc
				.getSuccessfulCumulativeCredits(getORMInterface());

		f.add(new Label("totalCredits", currCredits + ""));
		f.add(new Label("creditsEarned", creditsEarned + ""));
		f.add(new Label("sgpa", sgpa + ""));
		f.add(new Label("cumulativeCredits", cumulativeCredits + ""));
		f.add(new Label("cumulativeCreditsEarned", cumulativeCreditsEarned + ""));
		f.add(new Label("cgpa", cgpa + ""));
	}
	

	private static final long serialVersionUID = 3842090476704212756L;
}
